
package com.city.parking.map;

import java.util.HashMap;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;

import com.baidu.mapapi.map.offline.MKOLUpdateElement;
import com.baidu.mapapi.map.offline.MKOfflineMap;
import com.baidu.mapapi.map.offline.MKOfflineMapListener;
import com.city.parking.ParkingApp;
import com.city.parking.R;
import com.city.parking.util.Utils;


public class OfflineMapService extends Service implements MKOfflineMapListener {
//    LocationHandler mLocHandler;
//    ReverseAddrHandler mReverseHandler;

    public static final String TAG = "CdGeoService";
    private ParkingApp app = null;
    private NotificationManager mNotificationManager = null;
    private NotificationCompat.Builder mNotificationbuilder;
    private static final int NOTIFY_ID = 0;
    private MKOLUpdateElement updateInfo = null;

    private HashMap<Integer, Boolean> downloadQueue = new HashMap<Integer, Boolean>();
    public static final int NETWORK_STATUS_UPDATE_MSG = 200;
    private int cityCode = -1;

	private static OfflineMapService instance;	
	public static OfflineMapService get() {
		return instance;
	}
    
    private Handler mConnectivityHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {

        	switch (msg.what) {
        	case NETWORK_STATUS_UPDATE_MSG:// network state changed
        		log("nework state changed to: "+ParkingApp.network_status);
        		//if (mConnection != null) 
                {
                    switch (ParkingApp.network_status) {
                        case ParkingApp.NO_NETWORK:
                            for (HashMap.Entry<Integer, Boolean> entry : downloadQueue.entrySet())
                            {
                                    log(entry.getKey() + "/" + entry.getValue());
                                    // app.mOffline.pause(entry.getKey());
                                    instance.stopOfflineMapDownload(entry.getKey());
                            }
                            break;
                        case ParkingApp.MOBILE:
                        case ParkingApp.WIFI:
                            break;
                    }
                }
                
                break;
            
        	}
        }
    };
    
    private Handler mOMDownloadHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
    
           switch (msg.what) {
                case MKOfflineMap.TYPE_DOWNLOAD_UPDATE:
                    int localState = msg.getData().getInt("state");
                    updateInfo = app.mOffline.getUpdateInfo(localState);
                        
                    Log.e(TAG, "update notifications => service - ratio: "+updateInfo.ratio);
                           
                    if (updateInfo.ratio < 100) {
                        mNotificationbuilder.setContentText(updateInfo.cityName + " "
                                 + updateInfo.ratio + "%");
                    } else {
                        downloadQueue.remove(localState);
                        if (downloadQueue.size() == 0) {
                            mNotificationbuilder.setAutoCancel(true);
                            // mNotification.contentView = null;
                            Intent intent = new Intent(OfflineMapService.this, OfflineMapSettings.class);
                            intent.putExtra("completed", true);
                            PendingIntent contentIntent = PendingIntent.getActivity(OfflineMapService.this, 0, intent,
                                   PendingIntent.FLAG_UPDATE_CURRENT);
                            mNotificationbuilder.setContentText(updateInfo.cityName + " "
                                                    + "100%");
                            mNotificationbuilder.setContentTitle(getString(R.string.som_done_city));
                            mNotificationbuilder.setContentIntent(contentIntent);
                        }
        
                    }
                    mNotificationManager.notify(NOTIFY_ID, mNotificationbuilder.build());
                           
                break;                    
            }
         }
    };

    @Override
    public void onGetOfflineMapState(int type, int state) {
        //log("offline map => type is " + type + ", state is " + state);
        
        switch (type) {
        case MKOfflineMap.TYPE_DOWNLOAD_UPDATE:
            {
                Message OMUpdateMsg = mOMDownloadHandler.obtainMessage(MKOfflineMap.TYPE_DOWNLOAD_UPDATE);
                Bundle OMData = new Bundle();
                OMData.putInt("state", state);
                OMUpdateMsg.setData(OMData);
                OMUpdateMsg.sendToTarget();
                cityCode = state;
                Intent notifyOfflineMapIntent = new Intent(
                        OfflineMapSettings.ACTION_BROADCAST_OFFLINE_MAP_STATE_UPDATE);
                notifyOfflineMapIntent.putExtra("type", type);
                notifyOfflineMapIntent.putExtra("state", state);
                sendBroadcast(notifyOfflineMapIntent);
            }
            break;
        case MKOfflineMap.TYPE_NEW_OFFLINE:
            log(String.format("add offlinemap num:%d", state));
            break;
        case MKOfflineMap.TYPE_VER_UPDATE:
            MKOLUpdateElement e = app.mOffline.getUpdateInfo(state);
           log( "Update: "+e.cityName);
            break;
        }
    }
    
    

    @Override
    public void onCreate() {
        log("onCreate()");
        super.onCreate();
        app = (ParkingApp) OfflineMapService.this.getApplication();
        mNotificationManager = (NotificationManager) getSystemService(android.content.Context.NOTIFICATION_SERVICE);
        
        ParkingApp.get().registerForNetworkState(mConnectivityHandler, NETWORK_STATUS_UPDATE_MSG, null);

        instance = this;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        log("onStartCommand()");
//        if (FamilyApplication.sdkVersion <= 17) {
//            startForeground(1000, new Notification());
//        }
        return super.onStartCommand(intent, START_STICKY, startId);
    }

    @Override
    public IBinder onBind(Intent intent) {
        log("onBind()");
        return null;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        log("onUnbind()");
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        log("onDestroy()");
        // need clear all of pending request
        super.onDestroy();
		instance = null;
    }
    
    public void tryQuitService() {
    	stopForeground(true);
        if (downloadQueue.size() == 0) {
            log("quitService()");
            stopSelf();
        }
    }

    public boolean initOfflineMapInService() {
        // support offline map auto download
        boolean retVal = app.mOffline.init(OfflineMapService.this);
        log("offline map init returns " + retVal);

        return retVal;
    }

    public boolean startOfflineMapDownload(int cityID) {
        if (downloadQueue.size() == 0) {
            setUpNotification();
        }
        boolean retVal = app.mOffline.start(cityID);
        if (retVal) {
            downloadQueue.put(cityID, true);
            Toast.makeText(OfflineMapService.this, R.string.som_toast_map_download_start,
                    Toast.LENGTH_SHORT).show();
           log("service => offline map download start " + retVal);
        }

        return retVal;
    }

    public boolean stopOfflineMapDownload(int cityID) {
        boolean retVal = app.mOffline.pause(cityID);
        Intent notifyOfflineMapIntent = new Intent(
                OfflineMapSettings.ACTION_BROADCAST_OFFLINE_MAP_STATE_UPDATE);
        notifyOfflineMapIntent.putExtra("type", OfflineMapSettings.OFFLINE_MAP_STATE_REFRESH);
        notifyOfflineMapIntent.putExtra("state", cityCode);
        sendBroadcast(notifyOfflineMapIntent);

        return retVal;
    }

    public void startOfflineMapAutoUpgrade() {
    	/*
        if (ConfigInfo.upgrade_map_wifi_only && (app != null) && (app.mOffline != null)) {
            ArrayList<MKOLUpdateElement> rawList = null;
            // Bug 1965 note: null ptr happened inside baidu SDK, can not
            // reproduce
            // in normal case, try to catch and skip the exception
            try {
                initOfflineMapInService();
                rawList = app.mOffline.getAllUpdateInfo();
            } catch (NullPointerException e) {
                e.printStackTrace();
                // get debug info
                log("debug ==> app map view: " + app.mMapView);
                log("debug ==> app map controller: " + app.mMapController);
                return;
            }

            if (rawList == null) {
                log("local offline map list is empty");
            } else {
                log("local map items: " + rawList.size());
                for (MKOLUpdateElement localMapItem : rawList) {
                    if ((localMapItem.ratio >= 100) && (localMapItem.update)
                            && (localMapItem.status != MKOLUpdateElement.DOWNLOADING)) {
                        log("auto upgrade: " + localMapItem.cityName);
                        app.mOffline.remove(localMapItem.cityID);
                        startOfflineMapDownload(localMapItem.cityID);
                    }
                }
            }
        }
        */
    }

    private void setUpNotification() {
    	mNotificationbuilder = new NotificationCompat.Builder(this)
        .setContentText("")
        .setContentTitle(getString(R.string.som_btn_start_download))
        .setSmallIcon(R.drawable.ic_launcher)
        .setAutoCancel(false);
        

        Intent intent = new Intent(this, OfflineMapSettings.class);
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent,
                PendingIntent.FLAG_UPDATE_CURRENT);

        mNotificationbuilder.setContentIntent(contentIntent);
        mNotificationManager.notify(NOTIFY_ID, mNotificationbuilder.build());
    }

    private static void log(String msg) {
        Utils.log("GeoService " + msg);
    }
}
